iT邦幫忙

2021 iThome 鐵人賽

DAY 18
0
自我挑戰組

React自我學習心得30天~系列 第 18

Day18 Refs 和 DOM

  • 分享至 

  • xImage
  •  

React中若想將父層Component資料傳遞給子層Compontent的話,唯有使用Props方法,若需要用除此之外的方式更新作為child的DOM元素的話,就可以考慮使用ref。

ref使用時機

以下三種情況為ref建議的使用時機(參考react官網):

  • 管理 focus、選擇文字、或影音播放。
  • 觸發即時的動畫。
  • 與第三方 DOM 函式庫整合。

建立 Ref

使用React.createRef()便可以產生ref。Ref 常常會在一個 component 被建立出來的時候,被賦值在某個實例或DOM元素的屬性中,讓整個Component皆可以使用該屬性。以下為官網範例:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }
  render() {
    return <div ref={this.myRef} />;
  }
}

存取 Ref

當 ref在render中傳到一個元素的時候,便可以取得ref的current參數的。
Ref 的值會根據節點的類型而有所不同:

  • 當在 HTML標籤上使用 ref 參數時,使用 React.createRef() 建立 ref,便可以取得render中的DOM元素來做為它的 current 屬性。
  • 當在客製化的 class component 使用 ref 參數時,ref 取得被 mount 的 component上的實例來當作他的 current屬性。

HTML標籤上使用 ref 參數

class CustomTextInput extends React.Component {
  constructor(props) {
    super(props);
    // 產生一個可以儲存 textInput DOM element 的 ref
    this.textInput = React.createRef();
    this.focusTextInput = this.focusTextInput.bind(this);
  }

  focusTextInput() {
    // 利用ref的「current」來找出DOM節點 
    this.textInput.current.focus();
  }

  render() {
    // 在<input>上使用ref參數
    // 和 constructor 產生的 `textInput` 連結
    return (
      <div>
        <input
          type="text"
          ref={this.textInput} />
        <input
          type="button"
          value="Focus the text input"
          onClick={this.focusTextInput}
        />
      </div>
    );
  }
}

在 Class Component 加上 Ref

若想將上面的 CustomTextInput 包起來然後模擬它在被 mount 之後馬上被點擊,使用ref參數的話便可以取得CustomTextInput裡的<input>

class AutoFocusTextInput extends React.Component {
  constructor(props) {
    super(props);
    this.textInput = React.createRef();
  }

  componentDidMount() {
    this.textInput.current.focusTextInput();
  }

  render() {
    return (
      <CustomTextInput ref={this.textInput} />
    );
  }
}

上一篇
Day17 淺談Code-Splitting
下一篇
Day19 不使用JSX開發React的方式
系列文
React自我學習心得30天~30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言